#ifndef GOBAN_HPP
#define GOBAN_HPP

#include <QObject>
#include <QVector>
#include <QPair>
#include <QDebug>


class Goban : public QObject
{
    Q_OBJECT

public:
    Goban(quint8 size, QObject * parent);

    quint8 size() const;

    /*a case contains   0 if it is empty
                        1 if it has a white pawn
                        2 if it has a black pawn
                        3 if it has a "KO" tag
                        4 if it is a white stone in a black territory           (end of game)
                        5 if it is a black stone in a white territory           (end of game)
                        6 if it is an empty square in a white territory         (end of game)
                        7 if it is an empty square in a black territory         (end of game)

    */
    QVector< QVector<quint8> > map() const;
    void setMap(const QVector < QVector<quint8> > & map);
    void declareDead(int x, int y);
    void declareAlive(int x, int y);
    void debuging();
    void score(qreal & black, qreal & white) const;
    bool isATerritory(bool color, int x, int y);
    void display();

private:
    quint8 _size;
    QVector< QVector<quint8> > _map;
    QPair<int, int> _squareKO;

    bool _isACopy;

    bool isInRow(int x, int y) const;
    bool canExtend(QPair<int, int> pawn) const;
    bool isAlive(QVector <QPair<int, int> > group) const;
    void group_rec(int x, int y, QVector <QPair<int, int> > & group, quint8 color);
    QVector <QPair <int, int> > findGroup(int x, int y, bool color);
    void cleanMarkers(quint8 color);
    void deleteGroup(QVector <QPair< int, int> > group);
    bool isNotDead(bool color, int x, int y);
    void flood(QVector < QPair <int, int> > & map, bool color, int x, int y);
    QVector <QPair<int, int> > floodEmptyTerritory(bool color, int x, int y);
    void unmark(const QVector <QPair <int, int> > & group, quint8 marker);
    void remark(const QVector <QPair <int, int> > & group, quint8 marker, quint8 newMarker);
    static bool checkKO(Goban & gobanNew, const Goban & gobanOld, bool color, int x, int y);

public slots:
    /*
     * play a move, return  -42 if the move is not allowed
     *                      x, the number of stones caught
     */
   int playAMove(bool color, int x, int y);


};

#endif // GOBAN_HPP
